UserBackend.php

<?php  

namespace Tlf\User\Test;  

  
class UserBackend extends \Tlf\User\Tester {  

    /** @test $tester->get_active_user */
    public function testPasswordLogin2(){
        $password = 'def';
        $user = $this->get_active_user('reed@test.get_active_user', $password);
        $code = $user->password_login($password);
        $this->is_string($code);
    }

    public function testValidatePassword(){
        $ten = '1234567890';
        $seventy = $ten.$ten.$ten.$ten.$ten.$ten.$ten;
        $this->is_true(strlen($seventy)==70);
        $failures = [
            'short',
            '$4oRT',
            'no capitals1!',
            'No symbols123',
            'No numbers&',
            '72 chars is max size, bc BCRYPT limits'.$seventy
        ];
        $successes = [
            '12345aB!',
            'This 1 is good!',
            'With numbers 12&',
        ];

        $lib = new \Tlf\User\Lib($this->pdo());
            
        $this->test('failures');
        foreach ($failures as $f){
            $this->is_false($lib->is_password_valid($f));
            echo "   ".$f;
        }

        $this->test('successes');

        foreach ($successes as $s){
            $this->is_true($lib->is_password_valid($s));
        }
    }

    public function testLogout(){
        $pdo = $this->pdo();
        $lib = new \Tlf\User\Lib($pdo);
        $email = 'reed@test.logout';
        $user = $lib->user_from_email($email);
        $password = 'i like meditation. it makes me happier.';
        $user->register($password);
        $code = $user->new_code('registration');
        $user->activate($code);
        $cookie_code = $user->password_login($password);

        // i can't use set_login_cookie() because it uses `setcookie()` which modifies headers
        // $user->set_login_cookie($cookie_code);

        $user->set_login_cookie($cookie_code);
        // $_COOKIE[\Tlf\User::$cookie_name] = $cookie_code;

        $this->is_true($user->is_logged_in);

        $cookie_user = $lib->user_from_cookie();
        $this->is_object($cookie_user);

        $this->is_true($cookie_user->is_logged_in);

        $this->compare($_COOKIE[\Tlf\User::$cookie_name], $cookie_code);

        $user->logout();
        $this->is_true(empty($_COOKIE[\Tlf\User::$cookie_name]));
        
        // $_COOKIE[\Tlf\User::$cookie_name] = $cookie_code;
        $user->set_login_cookie($cookie_code);
        $no_user = $lib->user_from_cookie();
        $this->test("after logout, logging in with same cookie fails, even if its in the \$_COOKIE");
        $this->is_false($no_user);
    }
  
    public function testGetExistingUser(){

        $pdo = $this->pdo();
        $lib = new \Tlf\User\Lib($pdo);

        $email = 'reed@test.existing_user';
        $user = $lib->user_from_email($email);
        $password = "dance";
        $user->register($password);

        $get_user = $lib->user_from_email($email);

        $this->compare(
            [$user->email, $user->id, $user->is_active],
            [$get_user->email, $get_user->id, $get_user->is_active]
            
        );
    }

    public function testPasswordReset(){
        $pdo = $this->pdo();
        $lib = new \Tlf\User\Lib($pdo);

        $email = 'reed@test.password_reset';
        $user = $lib->user_from_email($email);
        $password = "dance";
        $user->register($password);
        $code = $user->new_code('registration');
        $user->activate($code);
        // $this->is_true($user->is_registered());
        // $this->is_true($user->is_active());

        $new_pass = 'Flop';

        $this->test('user can login with registered password');
        $this->is_string($user->password_login($password));
        $this->is_false($user->password_login($new_pass));

        $reset_code = $user->new_code('password_reset');

        $this->test('fail password change with bad code');
        $user->new_password($new_pass, 'bad-code');
        $this->is_string($user->password_login($password));
        $this->is_false($user->password_login($new_pass));

        $this->test("user can login with new password only");
        $user->new_password($new_pass, $reset_code);

        $this->is_string($user->password_login($new_pass));
        $this->is_false($user->password_login($password));


    }

    /** @test that a password cannot be updated if the reset-code is expired */
    public function testPasswordResetExpiration(){
        $pdo = $this->pdo();
        $lib = new \Tlf\User\Lib($pdo);

        $email = 'reed@test.password_reset_expired';
        $user = $lib->user_from_email($email);
        $user->password_reset_expiry = -10;
        $password = "dance";
        $new_password = "jive";
        $user->register($password);
        $code = $user->new_code('registration');
        $user->activate($code);

        $this->is_string($user->password_login($password));

        $reset_code = $user->new_code('password_reset');
        $this->is_false($user->new_password($new_password, $reset_code));

        $this->is_false($user->password_login($new_password));
        $this->is_string($user->password_login($password));
    }

    /** @test that an account cannot be activated with an expired registration code */
    public function testRegistrationExpiration(){
        $pdo = $this->pdo();
        $lib = new \Tlf\User\Lib($pdo);

        $email = 'reed@test.registration_expired';
        $user = $lib->user_from_email($email);
        $user->registration_expiry = -10;
        $password = "dance";
        $user->register($password);
        $code = $user->new_code('registration');
        $user->activate($code);
        $this->is_true($user->is_registered());
        $this->is_false($user->is_active());
    }

    public function testCookieExpiry(){

        $pdo = $this->pdo();
        $lib = new \Tlf\User\Lib($pdo);

        $email = 'reed@test.login_cookie_expired';
        $user = $lib->user_from_email($email);
        $user->cookie_expiry = -10;
        $password = "dance";
        $user->register($password);
        $code = $user->new_code('registration');
        $user->activate($code);
        $cookie_key = $user->password_login($password);
        // $_COOKIE[\Tlf\User::$cookie_name] = $cookie_key;
        $user->set_login_cookie($cookie_key);
        $this->is_true($user->is_logged_in);

        $this->is_false($user= $lib->user_from_cookie());
        // var_dump($user);
        // exit;
    }

    public function testCookieLogin(){

        $pdo = $this->pdo();
        $lib = new \Tlf\User\Lib($pdo);

        $email = 'reed@test.login_cookie';
        $user = $lib->user_from_email($email);
        $password = "dance";
        $user->register($password);
        $code = $user->new_code('registration');
        $user->activate($code);
        $cookie_key = $user->password_login($password);
        // $_COOKIE[\Tlf\User::$cookie_name] = $cookie_key;
        $user->set_login_cookie($cookie_key);
        $this->is_true($user->is_logged_in);

        $this->is_object($lib->user_from_cookie());
    }

    public function testPasswordLogin(){
        unset($_COOKIE['taeluf_login']);
        // $this->testCookieLogin();

        $pdo = $this->pdo();
        $lib = new \Tlf\User\Lib($pdo);

        $email = 'reed@test.login_password';
        $user = $lib->user_from_email($email);
        $password = "dance";

        $this->test("Login should fail before register");
        $this->is_false($user->is_logged_in);
        $this->is_false($user->password_login($password));

        $this->is_false($cookie_user = $lib->user_from_cookie());
        $this->is_false($user->is_logged_in);

        $this->is_int($user->register($password));

        // return;
        $this->test("Login should fail before activation,after registration");
        $this->is_false($user->password_login($password));
        $this->is_false($lib->user_from_cookie());

        $code = $user->new_code('registration');
        $user->activate($code);

        $this->test("Login should succeed after activation");
        $cookie_code = $user->password_login($password);
        // $_COOKIE[\Tlf\User::$cookie_name] = $cookie_code;
        $user->set_login_cookie($cookie_code);
        $this->is_true(strlen($cookie_code)>20);
        $this->is_true($user->is_logged_in);


        // idk about the cookie login here ...
        // $this->is_object($lib->user_from_cookie());
    }


    public function testPasswordHashing(){

        $pdo = $this->pdo();
        $ldb = new \Tlf\LilDb($pdo);
        $lib = new \Tlf\User\Lib($pdo);

        $email = 'reed@test.password_hash';
        $user = $lib->user_from_email($email);
        $user->register($password='password');
        $user = $ldb->select('user',['email'=>$email])[0];

        $this->password_verify($password, $user['password']);
        $this->is_true($password!=$user['password']);
    }

    public function testRegisterUser(){
        //@todo test that logging in with password 'no' does not work
        $pdo = $this->pdo();
        $ldb = new \Tlf\LilDb($pdo);
        $lib = new \Tlf\User\Lib($pdo);

        $email = 'reed@test.register';
        $user = $lib->user_from_email($email);

        $this->test("is_registered (not)");
        $this->is_false($user->is_registered());
        $this->compare($email, $user->email);

        $this->test('register');
        $id = $user->register('password');
        $this->is_int($id);
        $this->is_true($id!==false);

        $this->compare($id, $user->id);
        $this->compare($email, $user->email);

        $this->test("registered");

        $this->is_true($user->is_registered());
        $this->is_false($user->is_active());


        $this->test("new activation code");
        $code = $user->new_code('registration');

        $this->is_true($user->is_registered());
        $this->is_false($user->is_active());

        $this->test("Fake activation code should fail");
        $did_activate = $user->activate('not-a-real-code');
        $this->compare(false, $did_activate);

        $this->compare($ldb->select('user',['id'=>$user->id])[0]['is_active'], 0);

        $this->is_true($user->is_registered());
        $this->is_false($user->is_active());

        $this->test("activate");
        $this->is_true($user->activate($code));
        $this->compare($ldb->select('user', ['id'=>$user->id])[0]['is_active'], 1);

        $this->is_true($user->is_registered());
        $this->is_true($user->is_active());

        $this->test('(cannot) activate with same code');
        
        $this->is_false($user->activate($code));
        $this->is_true($user->is_active());

        $this->test('New registration code for already active user');
        $new_code = $user->new_code('registration');
        $this->is_true($user->is_active());
        $this->is_true($user->activate($new_code));
        $this->is_false($user->activate($new_code));

    }

    public function testInitDb(){
        $pdo = $this->pdo();
        $stmt = $pdo->query("SHOW TABLES;");

        $succeed = $this->compare(
            ['code', 'permissions', 'role_permission', 'security_log', 'throttle' ,'user', 'user_role'],
            $stmt->fetchAll(\PDO::FETCH_COLUMN)
        );

    }

}